//***************************************************************************
//*
//*	File:			DialogSmartReplace.h
//*	Description:	Smart replace dialog
//*
//***************************************************************************
//*
//*	Note:			This source code is provided "as is" meaning that you may 
//*					use it at your own risk. 
//*					You are free to use it in any way you like.
//*
//***************************************************************************
//*
//*	History:		
//*
//*	-------------------------------------------------------------------------
//*	2003/07/27	|	Initial release									|	rk
//*	-------------------------------------------------------------------------
//*
//***************************************************************************

//
//-------------------------------------------------------------- PREPROCESSOR 
//

#ifndef			__DIALOGSMARTREPLACE_H_INCLUDED
#define			__DIALOGSMARTREPLACE_H_INCLUDED

#if				_MSC_VER > 1000
#pragma once
#ifdef			__SWITCH_SHOW_HEADER
#pragma message ("-- DialogSmartReplace.h\n")
#endif
#ifdef			__SWITCH_SHOW_HEADER_TREE
#pragma message ("-- "__FILE__"\n")
#endif
#endif 

//
//-------------------------------------------------------------- DEPENDENCIES
//

//
//--------------------------------------------------------- CLASS DECLARATION
//

//***************************************************************************
//**	@DOC		CLASS CDialogSmartReplace
//***************************************************************************
//*		@CLASS		Dialog for managing configurations
//**	@BASE		Dialog
//**	@TODO	-	Add multi-line search/replace feature
//***************************************************************************
class CDialogSmartReplace : public CDialog
{
	//																									
	//-----------------------------------------------------------------------							
	//****************************     ENUMS     ****************************
	//-----------------------------------------------------------------------							
	//																									
private:																								// @ACCESS	Private Enumerations
	enum EHistroySize																					// @CMEMBER,MENUM	History size constants
	{																									//
		EHistroySize_Max			= 16																// @@EMEM	Maximum number of history entries to keep temporarily
	,	EHistroySize_Persistent_Max	= 16																// @@EMEM	Maximum number of history entries to keep persistent (to avoid overcrowding the registry)
	};																									
																										
	enum EFindStringMode																				// @CMEMBER,MENUM	Find string modes
	{																									//
		EFindStringMode_Discard																			// @@EMEM	Replace the find string with either the current selection or with the current line if there is no selection
	,	EFindStringMode_KeepIfNoSelection																// @@EMEM	Only keep the current find string mode when no text is selected
	,	EFindStringMode_Keep																			// @@EMEM	Always keep the current find string mode
	};																									
																										
	enum EReplaceWhere																					// @CMEMBER,MENUM	Replace locations
	{																									//
		EReplaceWhere_Selection																			// @@EMEM	Replace in selection
	,	EReplaceWhere_File																				// @@EMEM	Replace in current file
	,	EReplaceWhere_Extended																			// @@EMEM	Use extended replace location
	};																									
																										
	enum EReplaceWhereEx																				// @CMEMBER,MENUM	Extended replace locations
	{																									//
		EReplaceWhereEx_AllOpen																			// @@EMEM	Replcae in all open files
	,	EReplaceWhereEx_AllInProject																	// @@EMEM	Replaces in all project files
	,	EReplaceWhereEx_AllInWorkspace																	// @@EMEM	Replace in all workspace files
	,	EReplaceWhereEx_AllInDirectory																	// @@EMEM	Replace in all files matching filter settings for single directory
	,	EReplaceWhereEx_AllInFilters																	// @@EMEM	Replace in all files matching filter settings
	};																									
																										
	enum EUpdateData																					// @CMEMBER,MENUM	UpdateData flags
	{																									//
		EUpdateData_FromControls	= TRUE																// @@EMEM	Update members from controls
	,	EUpdateData_ToControls		= FALSE																// @@EMEM	Update controls from members
	};																									
																										
	enum EConfirmReplacement																			// @CMEMBER,MENUM	When to confirm replacments
	{																									//
		EConfirm_Never																					// @@EMEM	Never confirm replacements
	,	EConfirm_EachInstance																			// @@EMEM	Ask permission for each replacement
	,	EConfirm_EachFile																				// @@EMEM	Ask permission for each file
	,	EConfirm_EachProject																			// @@EMEM	Ask permission for each project
	};																									
																										
	enum ESaveAndClose																					// @CMEMBER,MENUM	When save and close
	{																									//
		ESaveAndClose_Never																				// @@EMEM	Never save and close opened documents
	,	ESaveAndClose_Always																			// @@EMEM	Always save and close opened documents
	,	ESaveAndClose_Ask																				// @@EMEM	Let the user chose each time
	};																									
																										
	enum EReplaceItem																					// @CMEMBER,MENUM	Replacement items
	{																									//
		EReplaceItem_Instance																			// @@EMEM	Single instance of the find string
	,	EReplaceItem_File																				// @@EMEM	Single file
	,	EReplaceItem_Project																			// @@EMEM	Single project
	};

	enum ECase																							// @CMEMBER,MENUM	Replace cases
	{																									// 
		ECase_AsIs																						// @@EMEM	Use the text as it is
	,	ECase_Lower																						// @@EMEM	Use the lower case version of the text
	,	ECase_Upper																						// @@EMEM	Use the upper case version of the text
	};																									

	enum EMenuRegExp																					// @CMEMBER,MENUM	Regular expression sub menu indices
	{																									//
		EMenuRegExp_Find																				// @@EMEM	Sub menu for find expressions
	,	EMenuRegExp_Replace																				// @@EMEM	Sub menu for replace expressions
	};

	enum ERegExpEmulation
	{
		ERegExpEmulation_DevStudio
	,	ERegExpEmulation_VC2
	,	ERegExpEmulation_Brief
	,	ERegExpEmulation_Epsilon
	,	ERegExpEmulation_Custom
	,	ERegExpEmulation_Count
	};

	enum ERegExpFind
	{
		ERegExpFind_AnyChar
	,	ERegExpFind_InRange
	,	ERegExpFind_NotInRange
	,	ERegExpFind_BeginOfLine
	,	ERegExpFind_EndOfLine
	,	ERegExpFind_TaggedExpression
	,	ERegExpFind_Not
	,	ERegExpFind_Or
	,	ERegExpFind_ZeroOrMore
	,	ERegExpFind_OneOrMore
	,	ERegExpFind_Group
	,	ERegExpFind_Whitespace
	,	ERegExpFind_AlphaNumericCharacter
	,	ERegExpFind_AlphaCharacter
	,	ERegExpFind_DecimalDigit
	,	ERegExpFind_HexNumber
	,	ERegExpFind_DecimalNumber
	,	ERegExpFind_Integer
	,	ERegExpFind_Identifier
	,	ERegExpFind_AlphabeticString
	,	ERegExpFind_QuotedString
	,	ERegExpFind_Count
	};

	enum ERegExpReplace
	{
		ERegExpReplace_FindWhatText
	,	ERegExpReplace_TaggedExpression1
	,	ERegExpReplace_TaggedExpression2
	,	ERegExpReplace_TaggedExpression3
	,	ERegExpReplace_TaggedExpression4
	,	ERegExpReplace_TaggedExpression5
	,	ERegExpReplace_TaggedExpression6
	,	ERegExpReplace_TaggedExpression7
	,	ERegExpReplace_TaggedExpression8
	,	ERegExpReplace_TaggedExpression9
	,	ERegExpReplace_Count
	};

	//																									
	//-----------------------------------------------------------------------							
	//***************************     CLASSES     ***************************
	//-----------------------------------------------------------------------							
	//																									
public:																									// @ACCESS	Public Classes
	class CFolder
	{
	public:
		CString	m_strPath	;
		BOOL	m_bRecurse	;
		BOOL	m_bEnabled	;

	public:
		CFolder& operator = ( const CFolder& a_Other )
		{
			this->m_strPath	 = a_Other.m_strPath ;
			this->m_bRecurse = a_Other.m_bRecurse;
			this->m_bEnabled = a_Other.m_bEnabled;

			return (*this);
		}

		CFolder( const CFolder& a_Other )
		: m_strPath	( a_Other.m_strPath  )
		, m_bRecurse( a_Other.m_bRecurse )
		, m_bEnabled( a_Other.m_bEnabled )
		{}

		CFolder( const CString& a_strPath, BOOL a_bRecurse = TRUE, BOOL a_bEnabled = TRUE )
		: m_strPath	( a_strPath  )
		, m_bRecurse( a_bRecurse )
		, m_bEnabled( a_bEnabled )
		{}

		CFolder()
		: m_strPath	( "" )
		, m_bRecurse( FALSE )
		, m_bEnabled( FALSE )
		{}
	};

	class CFileMask
	{
	public:
		CString	m_strMask	;
		BOOL	m_bEnabled	;

	public:
		CFileMask& operator = ( const CFileMask& a_Other )
		{
			this->m_strMask	 = a_Other.m_strMask ;
			this->m_bEnabled = a_Other.m_bEnabled;

			return (*this);
		}

		CFileMask( const CFileMask& a_Other )
		: m_strMask	( a_Other.m_strMask  )
		, m_bEnabled( a_Other.m_bEnabled )
		{}

		CFileMask( const CString& a_strMask, BOOL a_bEnabled = TRUE )
		: m_strMask	( a_strMask  )
		, m_bEnabled( a_bEnabled )
		{}

		CFileMask()
		: m_strMask	( "" )
		, m_bEnabled( FALSE )
		{}
	};

	class CSelectionPos
	{
	public:
		long m_lLine	;
		long m_lColumn	;

	public:
		bool operator == ( const CSelectionPos& a_Other ) const
		{
			return (this->m_lLine == a_Other.m_lLine) && (this->m_lColumn == a_Other.m_lColumn);
		}

		bool operator != ( const CSelectionPos& a_Other ) const
		{
			return (this->m_lLine != a_Other.m_lLine) || (this->m_lColumn != a_Other.m_lColumn);
		}

		CSelectionPos& operator = ( const CSelectionPos& a_Other )
		{
			this->m_lLine	= a_Other.m_lLine	;
			this->m_lColumn	= a_Other.m_lColumn	;

			return (*this);
		}

		CSelectionPos( const CSelectionPos& a_Other )
		: m_lLine	( a_Other.m_lLine	)
		, m_lColumn	( a_Other.m_lColumn )
		{}

		CSelectionPos( long a_lLine = -1, long a_lColumn = - 1 )
		: m_lLine	( a_lLine   )
		, m_lColumn	( a_lColumn )
		{}
	};

	typedef	CArray< CFolder			, CFolder&			> CFolderArray		;
	typedef	CArray< CFileMask		, CFileMask&		> CFileMaskArray	;
	typedef	CArray< CSelectionPos	, CSelectionPos&	> CSelectionPosArray;

	//																											
	//-----------------------------------------------------------------------									
	//***************************     ATTRIBS     ***************************									
	//-----------------------------------------------------------------------									
	//																											
private:																								// @ACCESS	Private Attributes	
	//{{AFX_DATA(CDialogSmartReplace)													
	enum { IDD = IDD_REPLACE };
	CComboBox			m_ctrlComboExtensions	;
	CComboBox			m_ctrlComboDirectory	;
	CComboBox			m_ctrlComboReplaceWith	;
	CComboBox			m_ctrlComboFindWhat		;
	CListCtrl			m_ctrlListFolders		;													
	CListCtrl			m_ctrlListFiles			;													
	CButton				m_ctrlBtnAdvanced		;													
	BOOL				m_bAllCases				;													
	BOOL				m_bMatchCase			;													
	BOOL				m_bRegularExpression	;													
	BOOL				m_bWholeWord			;													
	CString				m_strFindWhat			;													
	CString				m_strReplaceWith		;													
	int					m_iReplaceWhereEx		;													
	int					m_iReplaceWhere			;													
	CString				m_strDirectory			;
	CString				m_strExtensions			;
	BOOL				m_bRecurse				;
	//}}AFX_DATA
																						
	CIApplication		m_pIApplication			;														// @CMEMBER Smart pointer to application's interface
	EFindStringMode		m_enuFindStringMode		;														// @CMEMBER	The current find string mode
	EConfirmReplacement	m_enuConfirmReplacement	;														// @CMEMBER The current replacement confirmation mode
	ESaveAndClose		m_enuSaveAndClose		;														// @CMEMBER	The current save and close mode
	BOOL				m_bAborted				;														// @CMEMBER	Flag indicating whether replace operation has been aborted
	BOOL				m_bAskPermission		;														// @CMEMBER	Flag indicating whether to ask for permission (overrides user mode for non-exteded replace modes)
	BOOL				m_bAskForExtendedOnly	;														// @CMEMBER	Flag indicating whether to by-pass asking permissions for non-extended replace modes	

	CFolderArray		m_arrFolders			;														// @CMEMBER	Array of folders	to scan in "filters" mode
	CFileMaskArray		m_arrFileMasks			;														// @CMEMBER	Array of file masks to scan in "filters" mode

	BOOL				m_bSelectionMatches		;														// @CMEMBER	Flag indicating whether current selection matches the search criteria
	BOOL				m_bFileFinished			;														// @CMEMBER	Flag indicating whether all matches in the current file have been processed
	CSelectionPosArray	m_arrFoundMatches		;														// @CMEMBER	Array of matches found in current file

	ECase				m_enuCase				;														// @CMEMBER	Case of find string currently being processed
	long				m_lRegExpEmulation		;														// @CMEMBER Current regular expression emulation

	static const char*	ms_ppszRegExpFind		[ ERegExpFind_Count		][ ERegExpEmulation_Count ]	;	// @CMEMBER	Regular expressions for find text
	static const char*	ms_ppszRegExpReplace	[ ERegExpReplace_Count	][ ERegExpEmulation_Count ]	;	// @CMEMBER	Regular expressions for replace text

	//																							
	//-----------------------------------------------------------------------					
	//*************************     PERISTENCE     **************************					
	//-----------------------------------------------------------------------					
	//																							
private:																								// @ACCESS	Private Persistency Methods	
	void			LoadProfile				( void )												;	// @CMEMBER	Loads profile settings from the registry
	void			LoadHistory				( void )												;	// @CMEMBER	Loads profile settings from the registry
	void			LoadFilters				( void )												;	// @CMEMBER	Loads profile settings from the registry
	BOOL			WriteProfile			( void )										const	;	// @CMEMBER	Saves profile settings to   the registry
	BOOL			WriteHistory			( void )										const	;	// @CMEMBER	Saves profile settings to   the registry
	BOOL			WriteFilters			( void )										const	;	// @CMEMBER	Saves profile settings to   the registry
																						
	//																				
	//-----------------------------------------------------------------------		
	//***************************     HELPERS     ***************************		
	//-----------------------------------------------------------------------		
	//																				
private:																								// @ACCESS	Private Helper Methods	
	CITextDocument	GetTextDocument			( void )												;	// @CMEMBER	Determines the current text docuement's interface
	CITextSelection	GetTextSelection		( void )												;	// @CMEMBER	Determines the current text selection's interface
	DWORD			GetFindFlags			( void )										const	;	// @CMEMBER	Determines the find flags for the current settings
																		
	BOOL			AskSaveAndClose			( void 										)			;	// @CMEMBER	Asks for permission to save and closethe current document's window
	BOOL			AskPermission			(		EReplaceItem		a_enuItem		
											, const CString&			a_strName		)			;	// @CMEMBER	Asks for permission to replace the specified item
	void			AddText					(		CComboBox&			a_ctrlCombo		
											, const	CString&			a_strText		)			;	// @CMEMBER	Adds the specified text to the specified combo box
											
	//																				
	//-----------------------------------------------------------------------		
	//***************************     UPDATE     ****************************
	//-----------------------------------------------------------------------		
	//																				
private:																								// @ACCESS	Private Update Methods	
	void			UpdateAdvanced			( const CString&			a_strCaptionTo )			;	// @CMEMBER	Shows/hides advanced options
	void			UpdateControls			( void )												;	// @CMEMBER	Updates control's enabled/disabled states according to current member vars
	void			UpdateFindString		( void )												;	// @CMEMBER	Updates the find string
	void			UpdateFindStringEx		( void )												;	// @CMEMBER	Updates the find string
	void			UpdateHistories			( void )												;	// @CMEMBER	Updates the histories
	void			UpdateHistoryFind		( void )												;	// @CMEMBER	Updates the find history
	void			UpdateHistoryReplace	( void )												;	// @CMEMBER	Updates the replace history
	void			UpdateHistoryDirectory	( void )												;	// @CMEMBER	Updates the replace history
																								
	//																				
	//-----------------------------------------------------------------------		
	//***************************     REPLACE     ***************************
	//-----------------------------------------------------------------------		
	//																				
private:																								// @ACCESS	Private Replace Methods	
	BOOL			FindText				( void )												;	// @CMEMBER	Finds	 the next	 matching text
	BOOL			ReplaceStep				( const	CString&			a_strFind
											, const	CString&			a_strReplace
											,		DWORD				a_dwFlags		)			;	// @CMEMBER	Performs one replace step
											
	BOOL			ReplaceStepEx			( const	CString&			a_strFind
											, const	CString&			a_strReplace
											,		DWORD				a_dwFlags		
											,		BOOL				a_bAllCases		)			;	// @CMEMBER	Performs one replace step
	BOOL			ReplaceNext				( void )												;	// @CMEMBER	Replaces the current matching text
	int				ReplaceAll				( void )												;	// @CMEMBER	Replaces all occurences
											
	int				ReplaceAllSelection		( void )												;	// @CMEMBER	Replaces all occurences in current selection of current text document
	int				ReplaceAllOpen			( void )												;	// @CMEMBER	Replaces all occurences in all open			text files
	int				ReplaceAllProject		( void )												;	// @CMEMBER	Replaces all occurences in all project		text files
	int				ReplaceAllWorkspace		( void )												;	// @CMEMBER	Replaces all occurences in all workspace	text files
	int				ReplaceAllDirectory		( void )												;	// @CMEMBER	Replaces all occurences in all files in specified idrectory
	int				ReplaceAllFilters		( void )												;	// @CMEMBER	Replaces all occurences in all files in filter settings
											
	BOOL			FindText				( const	CString&			a_strFind
											,		DWORD				a_dwFlags		)			;	// @CMEMBER	Finds the specified text
	BOOL			FindTextEx				( const	CString&			a_strFind
											,		DWORD				a_dwFlags		
											,		BOOL				a_bAllCases		)			;	// @CMEMBER	Finds the specified text
	int				ReplaceAllFile			( const	CString&			a_strFile		
											,		BOOL				a_bText	= FALSE	)			;	// @CMEMBER	Replaces all occurences in specified file
	int				ReplaceAllProject		(		CIGenericProject	a_pIProject		)			;	// @CMEMBER	Replaces all occurences in specified project
	int				ReplaceAllDirectory		( const	CString&			a_strDirectory	
											, const	CString&			a_strFilter
											,		BOOL				a_bRecurse		)			;	// @CMEMBER	Replaces all occurences in specified directory
	int				ReplaceAllDirectoryEx	( const	CString&			a_strDirectory	
											, const	CString&			a_strExtensions
											,		BOOL				a_bRecurse		)			;	// @CMEMBER	Replaces all occurences in specified directory

	void			ResetMatches			( void )												;	// @CMEMBER	Resets the match record for the current file

	//																							
	//-----------------------------------------------------------------------					
	//**************************     VIRTUALS     ***************************
	//-----------------------------------------------------------------------					
	//																							
	//{{AFX_VIRTUAL(CDialogSmartReplace)
protected:																								// @ACCESS	Protected Overridables
	virtual void	DoDataExchange			( CDataExchange* pDX );										// @CMEMBER	DDX/DDV Support
	//}}AFX_VIRTUAL																						
	virtual	void	OnSearchComplete		( BOOL a_bMessageBox = TRUE )							;	// @CMEMBER	Called when the search completed and no more matches can be found
																										
	//																										
	//-----------------------------------------------------------------------								
	//**************************     MESSAGES     ***************************							
	//-----------------------------------------------------------------------								
	//																										
protected:																								// @ACCESS	Protected Message Handlers
	//{{AFX_MSG(CDialogSmartReplace)																
	virtual BOOL OnInitDialog					();														
	afx_msg void OnClose						();														
	afx_msg void OnContinue						();														
	afx_msg void OnReplace						();														
	afx_msg void OnReplaceAll					();														
	virtual void OnCancel						();														
	afx_msg void OnAdvanced						();														
	afx_msg void OnCheckMatchCase				();														
	afx_msg void OnCheckRegularExpression		();
	afx_msg void OnSelEndOkComboReplaceWhere	();														
	afx_msg void OnRadioSelection				();														
	afx_msg void OnRadioFile					();														
	afx_msg void OnRadioExtended				();														
	afx_msg void OnOptions						();																		
	afx_msg void OnDebug						();																			
	afx_msg void OnFilters						();
	afx_msg void OnBrowseDirectory				();
	afx_msg void OnContextMenuRegExpFind		();
	afx_msg void OnContextMenuRegExpReplace		();
												
	afx_msg	void OnCommandQuotedString			();
	afx_msg	void OnCommandAnyChar				();
	afx_msg	void OnCommandInRange				();
	afx_msg	void OnCommandNotInRange			();
	afx_msg	void OnCommandBeginOfLine			();
	afx_msg	void OnCommandEndOfLine				();
	afx_msg	void OnCommandTaggedExp				();
	afx_msg	void OnCommandNot					();
	afx_msg	void OnCommandOr					();
	afx_msg	void OnCommand0OrMore				();
	afx_msg	void OnCommand1OrMore				();
	afx_msg	void OnCommandGroup					();
	afx_msg	void OnCommandWhitespace			();
	afx_msg	void OnCommandAlphaNumericCharacter	();
	afx_msg	void OnCommandAlphaCharacter		();
	afx_msg	void OnCommandDecDigit				();
	afx_msg	void OnCommandHexNumber				();
	afx_msg	void OnCommandNumber				();
	afx_msg	void OnCommandInteger				();
	afx_msg	void OnCommandCIdentifier			();
	afx_msg	void OnCommandAlphabeticString		();
	afx_msg	void OnCommandFindWhatText			();
	afx_msg	void OnCommandTaggedExpression1		();
	afx_msg	void OnCommandTaggedExpression2		();
	afx_msg	void OnCommandTaggedExpression3		();
	afx_msg	void OnCommandTaggedExpression4		();
	afx_msg	void OnCommandTaggedExpression5		();
	afx_msg	void OnCommandTaggedExpression6		();
	afx_msg	void OnCommandTaggedExpression7		();
	afx_msg	void OnCommandTaggedExpression8		();
	afx_msg	void OnCommandTaggedExpression9		();
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()																			
																									
	//																								
	//-----------------------------------------------------------------------						
	//***********************     CON/DESTRUCTION     ***********************						
	//-----------------------------------------------------------------------						
	//																								
public:																									// @ACCESS	Public Con-/Destruction Methods	
	CDialogSmartReplace( IApplication* a_pIApplication, CWnd* pParent = NULL );							// @CMEMBER	Default constructor
};																									

//{{AFX_INSERT_LOCATION}}

#endif // #ifndef			__DIALOGSMARTREPLACE_H_INCLUDED
